
// 了解this机制的原理
// Call
Function.prototype.MyCall = function(obj) {
    if(typeof this !== "function") {
        throw "only function can use MyCall!";
    }
    const context = obj || window;
    context.MyCallFn = this;
    const args = [...arguments].slice(1);
    const result = context.MyCallFn(...args);
    delete context.MyCallFn;
    return result;
}

// Apply
// Apply 和 call的不同就是参数的传递
Function.prototype.MyApply = function(obj,args) {
    if(typeof this !== "function") {
        throw "only function can use MyApply!";
    }
    const context = obj || window
    context.MyBindFn = this;
    let result;
    if(args) {
        result = context.MyBindFn(...args);
    } else {
        result = context.MyBind();
    }
    delete context.MyBindFn;
    return result;
}


// Bind --- 返回一个函数
Function.prototype.MyBind = function(obj) {
    if(typeof this !== "function") {
        throw "only function can use MyBind!";
    }
    const context = obj || window;
    const _this = this;
    const args = [...arguments].slice(1);
    return function F() {
        if(this instanceof F) { //调用的是new
            return new _this(...args,...arguments);
        }
        return _this.apply(context,args.concat(...arguments));
    }
}   

function testThis() {
    console.log(this,arguments);
}

let me = {
    name: "lin"
};

testThis.MyCall(me,1,2,3);
testThis.MyApply(me,[1,2,3]);
const binder = testThis.MyBind(me,1);
binder(2);

// new
function create() {
    let obj = {};
    let Con = [].shift.call(arguments);
    obj.__proto__ = Con.prototype;
    let result = Con.apply(obj,arguments);
    return result instanceof Object ? result : obj;
}

function Man() {
    console.log(arguments);    
}

create(Man,1,2,3);


// instanceof
function myInstanceof(left,right) {
    let prototype = right.prototype;
    left = left.__proto__;
    while(true) {
        if(left===null || left === undefined) {
            return false;
        }
        if(left === prototype) {
            return true
        }
        left = left.__proto__;
    }
}

